import asyncio
import hashlib
from core.config import settings
import redis.asyncio as aioredis
from core.logger import log
from datetime import datetime

class AsyncRedisService:
    def __init__(self):
        self.redis_service = None
        self.redis_initialized = False

    async def init_redis(self):
        """异步初始化Redis连接池"""
        if not self.redis_initialized:
            self.redis_service = await aioredis.from_url(
                f"redis://:{settings.REDIS_PASSWORD}@{settings.REDIS_HOST}:{settings.REDIS_PORT}",  # 您的Redis地址
                decode_responses=True,  # 自动解码为字符串
                db=settings.REDIS_DB,
                max_connections=5  # 连接池大小
            )
            self.redis_initialized = True
            log.info("Redis连接池初始化成功")
    async def get_redis(self):
        """获取Redis客户端（自动初始化）"""
        if not self.redis_initialized:
            await self.init_redis()
        return self.redis_service

    async def close_redis(self):
        """关闭Redis连接"""
        if self.redis_initialized:
            await self.redis_service.close()
            self.redis_initialized = False
            log.info("Redis连接已关闭")

    # async def get_cached_label_list(self,key: str):
    #     cached = await self.redis_service.get(settings.REDIS_LABEL_KEY)
    #     if cached:
    #         return json.loads(cached)  # Redis 中是字符串，需反序列化
    #     # 如果缓存不存在，则调用接口获取
    #     label_list = await get_lable_list(key)
    #     await self.redis_service.set(settings.REDIS_LABEL_KEY, json.dumps(label_list), ex=settings.REDIS_TTL)
    #     return label_list
    async def set_phone_validate_code(self, phone: str, validate_code: str):
        """将手机号和验证码存到redis缓存中"""
        key = f"phone:{phone}"
        await self.redis_service.set(key, validate_code, ex=settings.REDIS_PHONE_CODE_TTL)

    async def set_base64(self, base64_str: str,fromUser: str,toUser: str):
        """将base64信息，存到redis缓存中"""
        key = f"base64:{fromUser}:{toUser}"
        await self.redis_service.lpush(key, base64_str)
        await self.redis_service.expire(key, 60 * 60 * 24)
    async def set_image_url(self, image_url: str,fromUser: str,toUser: str):
        """将图片url信息，存到redis缓存中"""
        key = f"image_url:{fromUser}:{toUser}"
        await self.redis_service.lpush(key, image_url)
        await self.redis_service.expire(key, 60 * 60 * 24)
    async def set_qw_sync_msg_cursor(self, cursor: str):
        """
        设置微信同步消息的游标
        """
        if self.redis_service is None:
            await self.init_redis()
        await self.redis_service.set("qw_sync_msg_cursor", cursor)
    async def set_moni_state(self):
        """设置监控状态"""
        await self.redis_service.set("monitor_trigger", "1",ex = 300)
    async def set_qw_access_token(self, access_token: str):
        """
        设置微信access_token
        """
        if self.redis_service is None:
            await self.init_redis()
        await self.redis_service.set("qw_access_token", access_token, ex=7200)
    async def set_ali_access_token(self, access_token: str, expire_time: int):
        """
        设置阿里access_token
        """
        await self.redis_service.set("ali_access_token", access_token, ex=expire_time)
    async def set_any(self, key: str, value: str, expire_time: int = None):
        """
        设置任意键值对
        """
        if expire_time is None:
            return await self.redis_service.set(key, value)
        return await self.redis_service.set(key, value, ex=expire_time)
    async def get_any(self, key: str):
        """
        获取任意键值对
        """
        return await self.redis_service.get(key)


    async def get_ali_access_token(self):
        """
        获取阿里access_token
        """
        return await self.redis_service.get("ali_access_token")

    async def get_phone_validate_code(self, phone: str):
        """
        获取手机号对应的验证码
        """
        key = f"phone:{phone}"
        return await self.redis_service.get(key)

    async def get_qw_sync_msg_cursor(self):
        """
        获取微信同步消息的游标
        """
        return await self.redis_service.get("qw_sync_msg_cursor")
    async def get_qw_access_token(self):
        """
        获取微信access_token
        """
        if self.redis_service is None:
            await self.init_redis()
        return await self.redis_service.get("qw_access_token")
    async def get_base64_list(self, fromUser: str, toUser: str, limit: int = None):
        """
        获取发送者和接收者之间的所有base64信息,后直接删除
        """
        key = f"base64:{fromUser}:{toUser}"
        if limit:
            # 获取指定数量的最新base64信息
            base64_list = await self.redis_service.lrange(key, 0, limit - 1)
        else:
            # 获取所有base64信息
            base64_list = await self.redis_service.lrange(key, 0, -1)
            await self.redis_service.delete(key)
        return base64_list
    async def get_image_urls_list(self,fromUser: str, toUser: str, limit: int = None):
        """
        获取图片URL列表
        """
        key = f"image_url:{fromUser}:{toUser}"
        if limit:
            # 获取指定数量最新的图片URL列表
            url_list = await self.redis_service.lrange(key, 0, limit - 1)
        else:
            # 获取所有图片URL列表
            url_list = await self.redis_service.lrange(key, 0, -1)
            await self.redis_service.delete(key)
        return url_list
    async def is_duplicate_msg(self, fromUser: str, toUser: str, content: str):
        # 生成唯一id(接收者，发送者，消息内容);
        msg_fingerprint = hashlib.sha256(
            f"{fromUser}:"
            f"{toUser}:"
            f"{content}".encode()
        ).hexdigest()
        redis_key = f"msg_fingerprint:{msg_fingerprint}"
        # client = await self.redis_service.get_redis()
        is_new = await self.redis_service.set(
            name=redis_key,
            value=1,
            ex=60 * 60 * 24 * 1,  # 1天
            nx=True
        )
        if is_new is None:
            log.info(f"跳过重复消息: {content}")
            return True
        return False
    async def qw_is_duplicate_msg(self, msg_id: str):
        """
        判断消息是否重复
        """
        key = f"qw_msg_id:{msg_id}"
        is_new= await self.redis_service.set(
            name=key,
            value=1,
            ex=60 * 60 * 24 * 1,  # 1天
            nx=True
        )
        if is_new is None:
            log.info(f"跳过重复消息: {msg_id}")
            return True
        return False
    async def mq_duplicate_msg(self, msg_id: str):
        # 获取消息指纹
        today_key = f"msg_ids:{datetime.now().strftime('%Y%m%d')}"
        is_new = await self.redis_service.sadd(today_key, msg_id)
        if is_new ==1:
            await self.redis_service.expire(today_key, 86400)  # 48小时过期
        return is_new == 0

    async def set_chat_mode(self, template_name: str):
        """
        设置聊天模式
        """
        await self.redis_service.rpush("chat_mode", template_name)
    async def get_chat_mode(self):
        """
        获取聊天模式
        """
        return await self.redis_service.lrange("chat_mode",0,-1)
    async def delete_chat_mode(self,template_name: str):
        """
        删除聊天模式
        """
        await self.redis_service.lrem("chat_mode",0,template_name)

    # 在类销毁时自动关闭连接
    def __del__(self):
        if self.redis_initialized:
            asyncio.create_task(self.close_redis())
